package cc.rengu.redp.flowable.controller;


import cc.rengu.redp.common.annotation.Log;
import cc.rengu.redp.common.controller.BaseController;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.domain.RedpResponse;
import cc.rengu.redp.flowable.bizrule.rule.BusiRuleCommander;
import cc.rengu.redp.flowable.bizrule.rule.BusiRulePrefix;
import cc.rengu.redp.flowable.delegate.DelegateManager;
import cc.rengu.redp.flowable.domain.ProcessDesignVo;
import cc.rengu.redp.flowable.listener.BizListenerManager;
import cc.rengu.redp.flowable.service.ProcessDesignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/process/design")
public class ProcessDesignController extends BaseController {

    @Autowired
    private ProcessDesignService processDesignService;

    @Log("流程定义查询")
    @GetMapping("list")
    public RedpResponse procDesignList(QueryRequest queryRequest, ProcessDesignVo processDesignVo) {
        try {
            return RedpResponse.getInstance().data(getDataTable(processDesignService.procDesignList(processDesignVo, queryRequest))).success();
        } catch (Exception e) {
            String message = "流程定义查询失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    @Log("保存流程定义")
    @PostMapping("saveFlow")
    public RedpResponse saveFlowDesignFromEditor(String editorJson) {
        try {
            processDesignService.saveFlowDesign(editorJson);
        } catch (Exception e) {
            String message = "流程定义保存失败：" + e.getMessage();
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("流程定义保存成功");
    }

    @Log("编辑流程定义")
    @GetMapping("editFlow")
    public RedpResponse editFlowDesignFromEditor(String modelId) {
        try {
            return RedpResponse.getInstance().data(processDesignService.getFlowDesignDesign(modelId)).success();
        } catch (Exception e) {
            String message = "流程定义读取失败：" + e.getMessage();
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    @Log("复制流程定义")
    @PostMapping("copyFlow")
    public RedpResponse copyFlowDesignFromEditor(String modelId) {
        try {
            processDesignService.copyFlowDesign(modelId);
            return RedpResponse.getInstance().success();
        } catch (Exception e) {
            String message = "流程定义复制失败：" + e.getMessage();
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    @Log("流程部署")
    @PostMapping("deploy")
    public RedpResponse deployProcDesign(String id) {
        try {
            processDesignService.deployProcDesign(id);
        } catch (Exception e) {
            log.error("流程部署异常", e);
            return RedpResponse.getInstance().failure().message("流程部署异常：" + e.getMessage());
        }

        return RedpResponse.getInstance().success().message("流程部署成功");
    }

    @GetMapping("getNodes")
    public RedpResponse listProcessAllNodes(String id) {
        try {
            return RedpResponse.getInstance().data(processDesignService.listProcessAllNodes(id)).success();
        } catch (Exception e) {
            String message = "流程节点查询失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
    }

    @GetMapping("getImage")
    public RedpResponse getFlowImage(String modelId) {
        try {
            return RedpResponse.getInstance().data(processDesignService.getFlowImage(modelId)).success();
        } catch (Exception e) {
            return RedpResponse.getInstance().failure().message("获取流程图失败");
        }
    }

    @Log("删除流程模型")
    @DeleteMapping("delete")
    public RedpResponse deleteModel(String modelId) {
        try {
            processDesignService.deleteProcDesign(modelId);
        } catch (Exception e) {
            String message = "删除流程模型失败：" + e.getMessage();
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
        return RedpResponse.getInstance().message("删除流程模型成功").success();
    }

    @Log("挂起流程实例")
    @PutMapping("suspend")
    public RedpResponse suspend(String modelId, Boolean allCurrentActiveInstances) {
        try {
            processDesignService.suspendDeployment(modelId, allCurrentActiveInstances);
        } catch (Exception e) {
            String message = "挂起已发布的模型失败：" + e.getMessage();
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
        return RedpResponse.getInstance().message("挂起已发布的模型成功").success();
    }

    @Log("激活流程实例")
    @PutMapping("active")
    public RedpResponse active(String modelId, Boolean allCurrentActiveInstances) {
        try {
            processDesignService.activeDeployment(modelId, allCurrentActiveInstances);
        } catch (Exception e) {
            String message = "挂起已发布的模型失败：" + e.getMessage();
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }
        return RedpResponse.getInstance().message("挂起已发布的模型成功").success();
    }

    /**
     * ServiceTask 列表
     * @return
     */
    @GetMapping("serviceTaskList")
    public Map<String, String> serviceTaskList() {
        return DelegateManager.getAll();
    }

    /**
     * Listener 列表
     * @return
     */
    @GetMapping("eventListenerList")
    public Map<String, String> eventListenerList() {
        return BizListenerManager.getAll();
    }

    /**
     * 流程自定义规则列表
     * @param rulePrefix
     * @return
     */
    @GetMapping("pluginRules/{rulePrefix}")
    public RedpResponse getRules(@PathVariable String rulePrefix) {
        if (rulePrefix.equals(BusiRulePrefix.CTRule.getRulePrefix())) {
            return RedpResponse.getInstance().data(BusiRuleCommander.showRulesForConfig(BusiRulePrefix.CTRule)).success();
        } else if (rulePrefix.equals(BusiRulePrefix.FSRule.getRulePrefix())) {
            return RedpResponse.getInstance().data(BusiRuleCommander.showRulesForConfig(BusiRulePrefix.FSRule)).success();
        } else if (rulePrefix.equals(BusiRulePrefix.ACCRule.getRulePrefix())) {
            return RedpResponse.getInstance().data(BusiRuleCommander.showRulesForConfig(BusiRulePrefix.ACCRule)).success();
        }

        return RedpResponse.getInstance().failure().message("rulePrefix error");
    }
}
